﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;

namespace Eg.Core.Data
{
    public class DataAccessObject<T,TId>
        where T : Entity<TId>
    {
        private readonly ISessionFactory _sessionFactory;

        private ISession session
        {
            get
            {
                return this._sessionFactory.GetCurrentSession();
            }
        }

        public DataAccessObject(ISessionFactory sessionFactory)
        {
            this._sessionFactory = sessionFactory;
        }

        public T Get(TId id)
        {
            return transact(() => session.Get<T>(id));
        }
        public T Load(TId id)
        {
            return transact(() => session.Load<T>(id));
        }
        public void Save(T entity)
        {
            transact(() => session.SaveOrUpdate(entity));
        }
        public void Delete(T entity)
        {
            transact(() => session.Delete(entity));
        }

        private TResult transact<TResult>(Func<TResult> func)
        {
            if (!session.Transaction.IsActive)
            {
                //Wrap in transaction
                TResult result;
                using (var tx = session.BeginTransaction())
                {
                    result = func.Invoke();
                    tx.Commit();
                }
                return result;
            }

            return func.Invoke();
        }
        private void transact(Action action)
        {
            transact<bool>(() =>
                {
                    action.Invoke();
                    return false;
                });
        }
    }

    public class DataAccessObject<T> : DataAccessObject<T, Guid> where T : Entity
    { }
}
